package com.weharvest.edu.service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.weharvest.edu.dao.BackstageUserDao;
import com.weharvest.edu.dao.mapper.BackstageRoleDaoMapper;
import com.weharvest.edu.dao.mapper.BackstageUserDaoMapper;
import com.weharvest.edu.dto.BackstageUserDTO;
import com.weharvest.edu.entity.BackstageRole;
import com.weharvest.edu.entity.BackstageUser;
import com.weharvest.edu.entity.between.BackstageUserInfo;
import com.weharvest.edu.enums.CommonEnums;
import com.weharvest.edu.enums.ResultEnum;
import com.weharvest.edu.exception.EduException;
import com.weharvest.edu.service.BackstageUserService;
import com.weharvest.edu.utlis.KeyUtil;
import com.weharvest.edu.utlis.SessionUtil;
import com.weharvest.edu.view.BackstageUserCpView;
import com.weharvest.edu.view.save.BackstageUserInfoSave;
import com.weharvest.edu.view.save.BackstageUserSuperiorSave;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.util.*;

@Service
@Slf4j
public class BackstageUserServiceImpl implements BackstageUserService {

    @Resource
    private BackstageUserDao backstageUserDao;

    @Resource
    private BackstageUserDaoMapper daoMapper;

    @Resource
    private BackstageUserDao dao;

    @Resource
    private BackstageRoleDaoMapper roleDaoMapper;

    @Override
    public Optional<BackstageUser> findByBackstageId(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new EduException(ResultEnum.BACKSTAGEUSER_FIND_INPUT_NODATA);
        }
        Optional<BackstageUser> option = backstageUserDao.findById(id);
        return option;
    }

    @Override
    public BackstageUser findByBackstageOpenid(BackstageUserDTO backstageUserDTO) {
        BackstageUser backstageUser = backstageUserDao.findByOpenid(backstageUserDTO.getOpenid());
        return backstageUser;
    }

    @Override
    public Map<String, Object> find(
            BackstageUserDTO dto,
            HttpServletRequest request,
            HttpServletResponse response) {
        if (null == dto || null == dto.getOrganizationId()) {
            log.error("[后台用户管理]查看用户列表，输入的参数不正确,dto={}", dto);
            throw new EduException(ResultEnum.BACKSTAGEUSER_PAGE_NOT_PARAMS);
        }
        Map<String, Object> result = new HashMap<>();
        String uid = SessionUtil.getSession(request, "uid");
        String organizationId = SessionUtil.getSession(request, "organizationId");

        //查询该用户所属的角色
        Map<String, Object> paramsByQueryByBR = new HashMap<>();
        paramsByQueryByBR.put("brFlag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        paramsByQueryByBR.put("brFlag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        paramsByQueryByBR.put("buUserId", uid);
        paramsByQueryByBR.put("buOrganizationId", organizationId);
        BackstageRole backstageRole = daoMapper.queryByBr(paramsByQueryByBR);

        //获取下级所属用户数据(不包含本身)
        PageHelper.startPage(dto.getPageNo(), dto.getPageSize(), "create_time desc");
        Map<String, Object> paramsByChildren = new HashMap<>();
        paramsByChildren.put("id", SessionUtil.getSession(request, "uid"));
        paramsByChildren.put("flag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        paramsByChildren.put("superiorFlag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        paramsByChildren.put("distanceR", 0);
        BackstageUserInfoSave backstageUserInfoSave = daoMapper.queryByClosureBuAndBrChildren(paramsByChildren);

        //下拉角色列表
        Map<String, Object> paramsByRoleList = new HashMap<>();
        paramsByRoleList.put("likeByPid", backstageRole.getPid());
        paramsByRoleList.put("flag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        paramsByRoleList.put("likeByName", dto.getLikeName());
        result.put("roles", roleDaoMapper.findByParams(paramsByRoleList));

        //整理获取所有用户id
        List<String> userList = new ArrayList<>();
        if (backstageUserInfoSave == null || backstageUserInfoSave.getSuperior() == null) {
            result.put("data", new PageInfo<>(new ArrayList<BackstageUserCpView>()));
            return result;
        }
        for (BackstageUserSuperiorSave busv : backstageUserInfoSave.getSuperior()) {
            userList.add(busv.getId());
        }

        //获取直属上级(获取直属父级)
        Map<String, Object> paramsByParent = new HashMap<>();
        paramsByParent.put("flag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        paramsByParent.put("superiorFlag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        paramsByParent.put("idIn", userList);
        paramsByParent.put("distance", 1);
        List<BackstageUserInfoSave> saveViewList = daoMapper.queryByClosureBuAndBrInParent(paramsByParent);
        result.put("data", new PageInfo<>(saveViewList));
        return result;
    }

    @Override
    @Transactional
    public void detele(
            BackstageUserDTO dto,
            HttpServletRequest request,
            HttpServletResponse response) {
        if (null == dto || StringUtils.isEmpty(dto.getId())) {
            log.error("[后台用户管理]删除后台用户失败，传入的数据不合法");
            throw new EduException(ResultEnum.BACKSTAGEUSER_ADD_FAIL);
        }
        //验证被删除的角色是否属于本用户下。
        String uid = SessionUtil.getSession(request, "uid");
        String organizationId = SessionUtil.getSession(request, "organizationId");
        BackstageUser backstageUser = new BackstageUser();
        Map<String, Object> paramsByChildren = new HashMap<>();
        paramsByChildren.put("id", SessionUtil.getSession(request, "uid"));
        paramsByChildren.put("flag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        paramsByChildren.put("superiorFlag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        BackstageUserInfoSave backstageUserInfoSave = daoMapper.queryByClosureBuChildren(paramsByChildren);
        if (backstageUserInfoSave.getSuperior() == null || backstageUserInfoSave.getSuperior().isEmpty()) {
            throw new EduException(ResultEnum.BACKSTAGEUSER_DELETE_RESULT_NODATA);
        }

//        for (BackstageUserSuperiorSave bu : backstageUserInfoSave.getSuperior()) {
//            //验证该用户是否存在要修改的用户
//            if (bu.getSuperiorId().equals(dto.getId())) {
//                bu.setUpdateTime(new Date());
//                bu.setFlag(CommonEnums.flag.FLAG_NO_AVAILABLE.getCode());
//                bu.setRoleId(null);
//                dao.save(bu);
//                return;
//            }
//        }
        throw new EduException(ResultEnum.BACKSTAGEUSER_DELETE_RESULT_NODATA);
    }


    @Override
    @Transactional
    public void add(BackstageUserDTO dto,
                    HttpServletRequest request,
                    HttpServletResponse response) {
        if (null == dto) {
            log.error("[后台用户管理]修改后台用户失败,传入的dto不能为空");
            throw new EduException(ResultEnum.BACKSTAGEUSER_MODIFY_INPUT_NODATA);
        }
        String uid = SessionUtil.getSession(request, "uid");
        String organizationId = SessionUtil.getSession(request, "organizationId");
        String password = dto.getPassword().equals("") ?
                CommonEnums.password.DEFAULT_PASSWORD.getCode().toString() : dto.getPassword();
        //新增用户
        BackstageUser newBackstage = new BackstageUser();
        String newId = KeyUtil.uuid();
        newBackstage.setId(newId);
        newBackstage.setPassword(KeyUtil.getEncryptionPassWord(password));
        newBackstage.setCreateTime(new Date());
        newBackstage.setOrganizationId(organizationId);
        newBackstage.setFlag(CommonEnums.flag.FLAG_AVAILABLE.getCode());
        newBackstage.setState(CommonEnums.state.STATE_NO_AVAILABLE.getCode());
        newBackstage.setName(dto.getName());
        newBackstage.setRoleId(dto.getRoleId());
        dao.save(newBackstage);
        //同时新增用户闭包表
        List<BackstageUserInfo> list = new ArrayList<>();
        //先查出用户闭包表中所有父级
        Map<String, Object> params = new HashMap<>();
        params.put("flag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        params.put("state", CommonEnums.state.STATE_AVAILABLE.getCode());
        params.put("pFlag", CommonEnums.flag.FLAG_AVAILABLE.getCode());
        params.put("id", uid);
        BackstageUserInfoSave backstageUserInfoSaveView = daoMapper.queryByClosureBuParent(params);
        List<BackstageUserInfo> infoList = new ArrayList<>();
        //数据整理
        for (BackstageUserSuperiorSave superiorSave : backstageUserInfoSaveView.getSuperior()) {
            BackstageUserInfo newInfo = new BackstageUserInfo();
            newInfo.setDistance(superiorSave.getOrder() + CommonEnums.number.DEFAULT_NUMBER_ONE.getCode());
            newInfo.setId(superiorSave.getId());
            newInfo.setCid(newId);
            infoList.add(newInfo);
        }
        //添加用户的本用户
        BackstageUserInfo rootInfo = new BackstageUserInfo();
        rootInfo.setId(newId);
        rootInfo.setCid(newId);
        rootInfo.setDistance(CommonEnums.number.DEFAULT_NUMBER_ZERO.getCode());
        infoList.add(rootInfo);
        daoMapper.addByBackstageUserInfo(infoList);
        return;
    }

    @Override
    @Transactional
    public void modify(BackstageUserDTO dto,
                       HttpServletRequest request,
                       HttpServletResponse response) {
        if (null == dto) {
            log.error("[后台用户管理]修改后台用户失败,传入的dto不能为空");
            throw new EduException(ResultEnum.BACKSTAGEUSER_MODIFY_INPUT_NODATA);
        }
        String uid = SessionUtil.getSession(request, "uid");
        BackstageUser backstageUser = dao.findByIdAndFlag(dto.getId(), CommonEnums.flag.FLAG_AVAILABLE.getCode());
        backstageUser.setUpdateTime(new Date());
        //判断是否为禁用
        if (dto.getState() != null) {
            backstageUser.setState(dto.getState());
            dao.save(backstageUser);
            return;
        }
        //修改用户表数据
        backstageUser.setName(dto.getName());
        backstageUser.setRoleId(dto.getRoleId());
        dao.save(backstageUser);
    }
}
